﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using wh40klbModel;
using wh40klbWeb.Models;

namespace wh40klbWeb.Controllers
{
    public class ArmyController : Controller
    {
        private WarhammerContext context = new WarhammerContext();
        public ActionResult Index()
        {
            List<ArmyViewModel> armies = context.Armies.Where(a => a.availible).Select(a => new ArmyViewModel() { Id = a.Id, Name = a.Name, Description = a.Description }).ToList();
            return View(armies);
        }
        public ActionResult Details(int id)
        {

            try
            {
                ArmyViewModel avm = GetArmyViewModel(id);
                if (avm == null) RedirectToAction("Index", "Army");
                return View(avm);
            }
            catch (Exception)
            {
                return RedirectToAction("Index", "Army");
            }
        }






        public ActionResult Create()
        {
            ArmyViewModel avm = new ArmyViewModel()
            {
                SquadTypesUsed = context.SquadTypes.Select(m => new SquadTypeUsedViewModel() { Name = m.Name, Id = m.Id }).ToList(),
                SpecialRulesUsed = context.SpecialRules.Select(sr => new ArmySpecialRulesUsedViewModel() { Name = sr.Name, Selected = false, Id = sr.Id }).ToList()
            };

            return View(avm);
        }
        [HttpPost]
        public ActionResult Create(ArmyViewModel avm)
        {
            try
            {
                if (!ModelState.IsValid) return View(avm);

                Army newArmy = new Army()
                {
                    Name = avm.Name,
                    Description = avm.Description,
                    availible = true
                };

                #region avm.SquadTypesUsed
                if (avm.SquadTypesUsed != null)
                {
                    foreach (var stu in avm.SquadTypesUsed)
                    {
                        newArmy.ArmySquadTypeUseds.Add(new ArmySquadTypeUsed
                        {
                            Army = newArmy,
                            SquadTypeId = stu.Id,
                            nbMaximum = stu.NbrMaximum,
                            nbMinimum = stu.NbrMinimum
                        });
                    }
                }
                #endregion

                #region avm.SpecialRulesUsed
                if (avm.SpecialRulesUsed != null)
                {
                    newArmy.SpecialRules = (from army in context.SpecialRules
                                            join srvm in avm.SpecialRulesUsed.Where(sr => sr.Selected).Select(sr => sr.Id) on army.Id equals srvm
                                            select army).ToList();
                }
                #endregion

                context.Entry(newArmy).State = System.Data.EntityState.Added;
                context.SaveChanges();

                return RedirectToAction("Index", "Army");
            }
            catch
            {
                return View(avm);
            }
        }




        public ActionResult Edit(int id)
        {
            try
            {
                ArmyViewModel avm = GetArmyViewModel(id);
                if (avm == null) RedirectToAction("Index", "Army");
                return View(avm);
            }
            catch (Exception ex)
            {
                return RedirectToAction("Index", "Army");
                //throw new HttpException(400,"Une erreur s'est produite lors de l'execution  de votre requete");             
            }
        }
        [HttpPost]
        public ActionResult Edit(int id, ArmyViewModel armyEdited)
        {
            try
            {
                Army armyToEdit = context.Armies.Find(id);

                List<SpecialRule> specialRules = context.SpecialRules.ToList();

                List<ArmySquadTypeUsed> SquadTypesUsed = context.ArmySquadTypesUsed.Where(stu => stu.ArmyId == id).ToList();

                if (armyEdited.Name != armyToEdit.Name || armyEdited.Description != armyToEdit.Description)
                {
                    armyToEdit.Name = armyEdited.Name;
                    armyToEdit.Description = armyEdited.Description;
                    context.Entry(armyToEdit).State = System.Data.EntityState.Modified;
                }
                context.Entry(armyToEdit).Collection(a => a.SpecialRules).Load();

                #region update specialRule
                foreach (var specialRuleUsed in armyEdited.SpecialRulesUsed)
                {
                    SpecialRule specialRule = specialRules.Find(sr => sr.Id == specialRuleUsed.Id);
                    if (specialRuleUsed.Selected)
                    {
                        if (specialRule.Armies.Count(a => a.Id == id) == 0)
                        {
                            specialRule.Armies.Add(armyToEdit);
                            context.Entry(specialRule).State = System.Data.EntityState.Modified;
                        }
                    }
                    else
                    {
                        if (specialRule.Armies.Count(a => a.Id == id) > 0)
                        {
                            armyToEdit.SpecialRules.Remove(specialRule);
                        }
                    }
                }
                #endregion

                foreach (SquadTypeUsedViewModel squadTypeUsed in armyEdited.SquadTypesUsed)
                {
                    ArmySquadTypeUsed astu = SquadTypesUsed.Find(ast => ast.ArmyId == id && ast.SquadTypeId == squadTypeUsed.Id);
                    if (astu != null && (astu.nbMaximum != squadTypeUsed.NbrMaximum || astu.nbMinimum != squadTypeUsed.NbrMinimum))
                    {
                        astu.nbMaximum = squadTypeUsed.NbrMaximum;
                        astu.nbMinimum = squadTypeUsed.NbrMinimum;
                        context.Entry(astu).State = System.Data.EntityState.Modified;
                    }
                }

                context.SaveChanges();
                return RedirectToAction("Index", "Army");
            }
            catch (Exception exe)
            {
                return View(armyEdited);
            }
        }




        public ActionResult Delete(int id)
        {
            try
            {
                ArmyViewModel avm = GetArmyViewModel(id);
                if (avm == null) RedirectToAction("Index", "Army");
                return View(avm);
            }
            catch (Exception)
            {
                return RedirectToAction("Index", "Home");
            }
        }
        [HttpPost]
        public ActionResult Delete(int id, ArmyViewModel armyDeleted)
        {
            try
            {
                Army army = context.Armies.Find(id);
                context.Entry(army).Collection(a => a.ArmySquadTypeUseds).Load();
                context.Entry(army).Collection(a => a.SpecialRules).Load();
                context.Entry(army).Collection(a => a.Infantries).Load();
                context.Entry(army).Collection(a => a.Squads).Load();
                context.Entry(army).Collection(a => a.Vehicules).Load();
                context.Entry(army).Collection(a => a.Wargears).Load();

                foreach (var item in army.ArmySquadTypeUseds)
                {
                    item.availible = false;
                    context.Entry(item).State = System.Data.EntityState.Modified;
                }
                foreach (var infantry in army.Infantries)
                {
                    infantry.availible = false;
                    context.Entry(infantry).Collection(i => i.SpecialRules).Load();
                    foreach (var specialRule in infantry.SpecialRules)
                    {
                        specialRule.availible = false;
                        context.Entry(specialRule).State = System.Data.EntityState.Modified;
                    }
                    context.Entry(infantry).State = System.Data.EntityState.Modified;
                }






                army.availible = false;
                context.Entry(army).State = System.Data.EntityState.Modified;
                context.SaveChanges();
                return RedirectToAction("Index", "Army");
            }
            catch (Exception ex)
            {
                return View(armyDeleted);
            }
        }



        private ArmyViewModel GetArmyViewModel(int id)
        {
            Army a = context.Armies.Find(id);
            if (!a.availible) RedirectToAction("Index", "Army");
            ArmyViewModel avm = new ArmyViewModel()
            {
                Name = a.Name,
                Description = a.Description,
                Id=a.Id
            };




            avm.SquadTypesUsed =
                (context.ArmySquadTypesUsed.Count(stu => stu.ArmyId == a.Id) >= 0) ?
                    context.ArmySquadTypesUsed.Where(stu => stu.ArmyId == a.Id)
                    .Select(st => new SquadTypeUsedViewModel()
                    {
                        Name = st.SquadType.Name,
                        NbrMaximum = st.nbMaximum,
                        NbrMinimum = st.nbMinimum
                    })
                    .ToList()
                    : null;

            avm.SpecialRulesUsed = context
                .SpecialRules.Where(sr=>sr.availible)
                .Select(sr => new ArmySpecialRulesUsedViewModel()
                {
                    Id = sr.Id,
                    Name = sr.Name,
                    Selected = sr.Armies.Count(ar => ar.availible && ar.Id == a.Id) > 0
                })
                .ToList();

            return avm;
        }
    }
}
